#include <QCheckBox>
#include <QMessageBox>
#include <QDir>
#include <QDebug>
#include <fstream>
#include <regex>

#include "SmartSerial.h"
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "PortItem.h"
#include "utils/StringUtils.h"

using namespace StringUtils;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pb_send->setEnabled(false);
    ui->pb_recv->setEnabled(false);

    initMap();

    auto ports = serial::list_ports();
    for(size_t i = 0; i < ports.size(); i++) {
        auto item = std::make_shared<Item>();
        items.push_back(item);
        item->port = ports[i].port;
        item->serial = std::make_shared<SmartSerial>(item->port);
        item->at = std::make_shared<AT>([serial = item->serial](const char* d,size_t s){
            serial->write((uint8_t*)d, s);
        });
        item->serial->setOnOpenHandle([](bool isopen){
        });
        item->serial->setOnReadHandle([at = item->at](const uint8_t* d,size_t s){
            at->onData(std::string((char*)d, s));
        });
    }
    updateList();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pb_close_clicked()
{
}

void MainWindow::on_pb_open_clicked()
{
}

void MainWindow::on_pb_send_clicked()
{
    auto phone_to = ui->le_phone_to->text().toStdString();
    if (phone_to.empty()) {
        QMessageBox::information(this, "", "发送手机号不能为空");
        return;
    }

    auto context = ui->te_content->toPlainText().toStdString();
    if (context.empty()) {
        QMessageBox::information(this, "", "内容不能为空");
        return;
    }

    auto& AT = itemFound->at;
    AT->cmd("CMGF=1");
    auto msg = format("CMGW=\"+86%s\"", phone_to.c_str());
    AT->cmd(msg.c_str());
    AT->raw(context);
    std::string end;
    end.push_back(0x1A);
    auto ret = AT->raw(end, 500);
    qDebug() << "RET: " << ret.c_str();
    QMessageBox::information(this, "", QS(ret));
}

void MainWindow::initMap() {
    using namespace std;
    ifstream file;
    auto filePath = QCoreApplication::applicationDirPath() + "/phone_ccid.txt";
    qDebug() << "path:"<<filePath;
    file.open(filePath.toStdString().c_str(), ios::in);
    assert(file.is_open());

    static std::string regex_str = "(.*)----(.*)";
    static std::regex re(regex_str);

    std::string strLine;
    while(getline(file,strLine)) {
        std::smatch results;
        if (std::regex_search(strLine, results, re)) {
            phoneCCID.insert({results[1].str(), results[2].str()});
            ccidPhone.insert({results[2].str(), results[1].str()});
        }
    }
    qDebug() << "phoneccid:" << phoneCCID.size();
}

void MainWindow::on_le_phone_editingFinished()
{
    auto phone = ui->le_phone->text().toStdString();
    auto iter = std::find_if(items.cbegin(), items.cend(), [&phone](const auto& item) {
        return item->phone == phone;
    });
    if(iter != items.cend()) {
        const auto& item = *iter;
        ui->ccid_found->setText(QS(format("串口:%s CCID:%s", item->port.c_str(), item->ccid.c_str())));
        itemFound = item;
        ui->pb_send->setEnabled(true);
        ui->pb_recv->setEnabled(true);
    } else {
        ui->ccid_found->setText("未找到此手机号对应的串口");
        itemFound = nullptr;
        ui->pb_send->setEnabled(false);
        ui->pb_recv->setEnabled(false);
    }
}

void MainWindow::on_bp_update_clicked()
{
    updateList();
}

void MainWindow::updateList() {
    auto list = ui->lw_serial;
    list->clear();
    int i = 1;
    for(auto& item : items) {
        auto r = item->at->cmd("CCID");
        auto r2 = QS(r).split("\r\n");
        if (r2.size() < 2) {
            item->ccid = "";
        } else {
            item->ccid = r2.at(1).toStdString();
        }
        auto iter = ccidPhone.find(item->ccid);
        if (iter != ccidPhone.cend()) {
            item->phone = iter->second;
        }
        list->addItem(QS(format("%-10d %s  %s  %s", i++, item->port.c_str(), item->ccid.c_str(), item->phone.c_str())));
    }
}

void MainWindow::on_lw_serial_currentRowChanged(int currentRow)
{
    if (currentRow<0 || currentRow>int(items.size()-1)) return;
    ui->le_phone->setText(QS(items[currentRow]->phone));
    emit on_le_phone_editingFinished();
}

void MainWindow::on_pb_recv_clicked()
{
    ui->tb_sms->setText("请稍后...");
    auto ret = itemFound->at->cmd("CMGL", 1000);
    ui->tb_sms->setText(QS(ret));
}
